#include "viewcontainerwidget.h"

#include "dicomimageview.h"
#include "Global/commondefs.h"
#include "../ImageData/seriesinstance.h"
#include "../ImageData/imageinstance.h"
#include "exportimagedialog.h"
#include "dcmtk/dcmdata/dcdeftag.h"
#include <QGridLayout>
#include <QResizeEvent>
#include <QKeyEvent>
#include <QFontDialog>
#include <QSettings>
#include <QApplication>
#include <QClipboard>

ViewContainerWidget::ViewContainerWidget(QWidget *parent) :
    curView(0),
    maxed(0),
    layout(new QGridLayout(this)),
    filter(0),
    QWidget(parent)
{
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);

    QFont f;
    if (f.fromString(QSettings().value(ANNO_TEXT_FONT).toString()))
        annoFont = f;

    setViewLayout(1, 1);
}

ViewContainerWidget::~ViewContainerWidget()
{
    QSettings().setValue(ANNO_TEXT_FONT, annoFont.toString());
}

void ViewContainerWidget::onSeriesInserted(SeriesInstance *series)
{
    if (!series) return;
    DicomImageView *view = 0;

    if (series->getTagKeyValue(DCM_Modality) == "MG") {
        setViewLayout(2, 2);
        QString lat = series->getTagKeyValue(DCM_Laterality);
        QString pos = series->getTagKeyValue(DCM_ViewPosition);
        if (lat == "R") {
            if (pos == "CC") {
                view = viewList.at(0);
            } else if (pos == "MLO") {
                view = viewList.at(2);
            }
        } else if (lat == "L") {
            if (pos == "CC") {
                view = viewList.at(1);
            } else if (pos == "MLO") {
                view = viewList.at(3);
            }
        }
    } else {
        foreach (DicomImageView *v, viewList) {
            if (!v->hasSeries()) {
                v->setSeriesInstance(series);
                view = v;
                break;
            }
        }
    }

    if (view) {
        view->setSeriesInstance(series);
        if (!(curView && curView != view))
            onViewClicked(view);
    }
}

void ViewContainerWidget::onSeriesRemove(SeriesInstance *series)
{
    foreach (DicomImageView *view, viewList) {
        if (view->getSeriesInstance() == series)
            view->clear();
    }
}

void ViewContainerWidget::onImageDClicked(SeriesInstance *series)
{
    if (series && series->getTagKeyValue(DCM_Modality) == "MG")
        onSeriesInserted(series);
    else {
        if (curView) curView->setSeriesInstance(series);
    }
}

void ViewContainerWidget::onImageChanged(SeriesInstance *series)
{
    if (!series) return;
    foreach (DicomImageView *v, viewList) {
        if (v->getSeriesInstance() == series) {
            onViewClicked(v);
            break;
        }
    }
}

void ViewContainerWidget::onViewImageChanged()
{
    if (curView) emit curViewChanged(curView->getSeriesInstance());
}

void ViewContainerWidget::onViewClicked(DicomImageView *view)
{
    if (curView) curView->setHighlight(false);
    curView = view;
    if (curView) {
        curView->setHighlight(true);
        emit curViewChanged(curView->getSeriesInstance());
    }
}

void ViewContainerWidget::onViewDClicked(DicomImageView *view)
{
    if (!view) return;
    if (maxed) {
        foreach (DicomImageView *v, viewList) {
            v->setVisible(true);
        }
        maxed = false;
    } else {
        foreach (DicomImageView *v, viewList) {
            v->setVisible(false);
        }
        view->setVisible(true);
        maxed = true;
    }
}

void ViewContainerWidget::setViewLayout(int col, int row)
{
    if (!(col > 0 && row > 0)) return;
    if (maxed) onViewDClicked(curView);

    int cellWidth = contentsRect().width() / col;
    int cellHeight = contentsRect().height() / row;
    foreach (DicomImageView *v, viewList) {
        layout->removeWidget(v);
    }

    int viewCount = col * row;
    while (viewCount < viewList.size()) {
        DicomImageView *v = viewList.takeLast();
        curView = (curView==v)?0:curView;
        delete v;
    }

    DicomImageView *view;
    for (int i = 0; i < row; ++i) {
        for (int j = 0; j < col; ++j) {
            if (i * col + j < viewList.size()) {
                view = viewList[i * col + j];
                view->setSizeHint(QSize(cellWidth, cellHeight));
            } else {
                view = createImageView();
                view->setSizeHint(QSize(cellWidth, cellHeight));
                //if (maxed) view->setVisible(false);
                viewList << view;
            }
            layout->addWidget(view, i, j);
        }
    }

    if ((!curView) && (!viewList.isEmpty())) onViewClicked(viewList.first());
    if (curView) emit curViewChanged(curView->getSeriesInstance());
}

DicomImageView *ViewContainerWidget::createImageView()
{
    DicomImageView *v = new DicomImageView;
    v->setModalityProperty(&prop);
    v->setAnnoTextFont(annoFont);
    v->installEventFilter(filter);
    connect(v, SIGNAL(viewClicked(DicomImageView*)),
            this, SLOT(onViewClicked(DicomImageView*)));
    connect(v, SIGNAL(viewDoubleclicked(DicomImageView*)),
            this, SLOT(onViewDClicked(DicomImageView*)));
    //connect(v, SIGNAL(imageChanged()), this, SLOT(onViewImageChanged()));
    return v;
}

void ViewContainerWidget::setPrintMode(bool yes)
{
    if (yes) {
        foreach (DicomImageView *v, viewList) {
            v->setViewMode(DicomImageView::VM_Print);
        }
    } else {
        foreach (DicomImageView *v, viewList) {
            v->setViewMode(DicomImageView::VM_Observe);
        }
        layout->setContentsMargins(0, 0, 0, 0);
    }
}

void ViewContainerWidget::clear()
{
    foreach (DicomImageView *v, viewList) {
        v->clear();
        v->reset();
        v->setVisible(true);
    }
    maxed = false;
}

void ViewContainerWidget::exportImages()
{
    if (curView && curView->getSeriesInstance()) {
        ImageInstance *inst = curView->getSeriesInstance()->getCurrImageInstance(VT_XYPlane);
        if (inst) {
            ExportImageDialog d;
            d.setImageFiles(QStringList()<<inst->getImageFile());
            d.exec();
        }
    }
}

void ViewContainerWidget::copyToClipboard()
{
    if (curView) {
        QApplication::clipboard()->setPixmap(curView->getHardCopyPixmap());
    }
    /*
    if (curView && curView->getSeriesInstance()) {
        QPixmap pixmap;
        if (curView->getSeriesInstance()->getPixmap(pixmap, VT_XYPlane)){
            QApplication::clipboard()->setPixmap(pixmap);
        }
    }
    */
}

void ViewContainerWidget::showAnnotations(bool yes)
{
    foreach (DicomImageView *v, viewList) {
        v->showAnnotations(yes);
    }
}

void ViewContainerWidget::showMeasurements(bool yes)
{
    foreach (DicomImageView *v, viewList) {
        v->showMeasurements(yes);
    }
}

void ViewContainerWidget::showCrossRefLine(bool yes)
{

}

void ViewContainerWidget::showDicomTags()
{

}

void ViewContainerWidget::adjustWL()
{
    if (curView) curView->adjustWL();
}

void ViewContainerWidget::setDefaultWL()
{
    if (curView) curView->setDefaultWL();
}

void ViewContainerWidget::setFullDynamic()
{
    if (curView) curView->setFullDynamic();
}

void ViewContainerWidget::zoomImage()
{
    if (curView) curView->zoomImage();
}

void ViewContainerWidget::setFillViewport()
{
    if (curView) curView->setFillViewport();
}

void ViewContainerWidget::setZoom100()
{
    if (curView) curView->setZoom100();
}

void ViewContainerWidget::setZoom200()
{
    if (curView) curView->setZoom200();
}

void ViewContainerWidget::setZoom400()
{
    if (curView) curView->setZoom400();
}

void ViewContainerWidget::setZoomin()
{
    if (curView) curView->setZoomin();
}

void ViewContainerWidget::setZoomout()
{
    if (curView) curView->setZoomout();
}

void ViewContainerWidget::panImage()
{
    if (curView) curView->panImage();
}

void ViewContainerWidget::resetPan()
{
    if (curView) curView->resetPan();
}

void ViewContainerWidget::slicing()
{
    if (curView) curView->slicing();
}

void ViewContainerWidget::rotateCCW()
{
    if (curView) curView->rotateCCW();
}

void ViewContainerWidget::rotateCW()
{
    if (curView) curView->rotateCW();
}

void ViewContainerWidget::clearRotate()
{
    if (curView) curView->clearRotate();
}

void ViewContainerWidget::hFlip()
{
    if (curView) curView->hFlip();
}

void ViewContainerWidget::vFlip()
{
    if (curView) curView->vFlip();
}

void ViewContainerWidget::clearFlip()
{
    if (curView) curView->clearFlip();
}

void ViewContainerWidget::invert()
{
    if (curView) curView->inverseImage();
}

void ViewContainerWidget::magnifier()
{
    if (curView) curView->magnifier();
}

void ViewContainerWidget::drawLength()
{
    if (curView) curView->drawLenght();
}

void ViewContainerWidget::drawAngle()
{
    if (curView) curView->drawAngle();
}

void ViewContainerWidget::drawCobbAngle()
{
    if (curView) curView->drawCobbAngle();
}

void ViewContainerWidget::drawEllipse()
{
    if (curView) curView->drawEllipse();
}

void ViewContainerWidget::drawRectangle()
{
    if (curView) curView->drawRectangle();
}

void ViewContainerWidget::drawPencil()
{
    if (curView) curView->drawPencil();
}

void ViewContainerWidget::drawText()
{
    if (curView) curView->drawText();
}

void ViewContainerWidget::drawArrow()
{
    if (curView) curView->drawArrow();
}

void ViewContainerWidget::rmAllMeasurements()
{
    if (curView) curView->rmAllMeasurements();
}

void ViewContainerWidget::incAnnoFont()
{
    annoFont.setPointSize(annoFont.pointSize() + 1);
    foreach (DicomImageView *v, viewList) {
        v->setAnnoTextFont(annoFont);
    }
}

void ViewContainerWidget::decAnnoFont()
{
    annoFont.setPointSize(annoFont.pointSize() - 1);
    foreach (DicomImageView *v, viewList) {
        v->setAnnoTextFont(annoFont);
    }
}

void ViewContainerWidget::setAnnoFont()
{
    annoFont = QFontDialog::getFont(0, annoFont, this);
    foreach (DicomImageView *v, viewList) {
        v->setAnnoTextFont(annoFont);
    }
}

void ViewContainerWidget::reset()
{
    if (curView) curView->reset();
}

void ViewContainerWidget::prevView()
{
    if (curView && viewList.size()) {
        int i = viewList.indexOf(curView);
        if (i > 0) onViewClicked(viewList.at(i-1));
    }
}

void ViewContainerWidget::nextView()
{
    if (curView && viewList.size()) {
        int i = viewList.indexOf(curView);
        if (i < viewList.size()-1) onViewClicked(viewList.at(i+1));
    }
}

void ViewContainerWidget::nextFrame()
{
    if (curView) curView->nextFrame();
}

void ViewContainerWidget::prevFrame()
{
    if (curView) curView->prevFrame();
}

void ViewContainerWidget::resizeEvent(QResizeEvent *e)
{
    QWidget::resizeEvent(e);
}
/*
void ViewContainerWidget::keyPressEvent(QKeyEvent *e)
{
    switch (e->key()) {
    case Qt::Key_Home:
        if (curView && (curView != viewList.first())) {
            curView->setHighlight(false);
            curView = viewList.first();
            curView->setHighlight(true);
            emit curViewChanged(curView->getSeriesInstance());
        } else if ((!curView) && viewList.size()) {
            curView = viewList.first();
            curView->setHighlight(true);
            emit curViewChanged(curView->getSeriesInstance());
        }
        break;
    case Qt::Key_PageDown:
    case Qt::Key_Down:
    case Qt::Key_Right:
        if (curView && (viewList.size()>1)) {
            curView->setHighlight(false);
            if (curView == viewList.last()) curView = viewList.first();
            else curView = viewList.at(viewList.indexOf(curView)+1);
            curView->setHighlight(true);
            emit curViewChanged(curView->getSeriesInstance());
        } else if (viewList.size()) {
            curView = viewList.first();
            curView->setHighlight(true);
            emit curViewChanged(curView->getSeriesInstance());
        }
        break;
    case Qt::Key_End:
        if (curView && (curView != viewList.last())) {
            curView->setHighlight(false);
            curView = viewList.last();
            curView->setHighlight(true);
            emit curViewChanged(curView->getSeriesInstance());
        } else if ((!curView) && viewList.size()) {
            curView = viewList.last();
            curView->setHighlight(true);
            emit curViewChanged(curView->getSeriesInstance());
        }
        break;
    case Qt::Key_PageUp:
    case Qt::Key_Up:
    case Qt::Key_Left:
        if (curView && (viewList.size()>1)) {
            curView->setHighlight(false);
            if (curView == viewList.first()) curView = viewList.last();
            else curView = viewList.at(viewList.indexOf(curView)-1);
            curView->setHighlight(true);
            emit curViewChanged(curView->getSeriesInstance());
        } else if (viewList.size()) {
            curView = viewList.last();
            curView->setHighlight(true);
            emit curViewChanged(curView->getSeriesInstance());
        }
        break;
    default:
        QWidget::keyPressEvent(e);
    }
}
*/
